package service

import (
	"errors"
	"wms/internal/model"
	"wms/internal/model/request"
	"wms/pkg/global"
	"wms/pkg/logger"
	"wms/pkg/utils"

	"gorm.io/gorm"
)

type CargoService struct {
	db *gorm.DB
}

func NewCargoService() *CargoService {
	return &CargoService{
		db: global.DB,
	}
}

// CreateCargo 创建货物
func (s *CargoService) CreateCargo(req *request.CreateCargoRequest, userID uint) error {
	// 检查货物编码是否已存在
	var count int64
	if err := global.DB.Model(&model.Cargo{}).Where("code = ?", req.Code).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("货物编码已存在")
	}

	// 检查分类是否存在
	var category model.CargoCategory
	if err := global.DB.First(&category, req.CategoryID).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("货物分类不存在")
		}
		return err
	}

	// 如果提供了供应商ID，检查供应商是否存在
	if req.SupplierID != nil && *req.SupplierID > 0 {
		var supplier model.Supplier
		if err := global.DB.First(&supplier, *req.SupplierID).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return errors.New("供应商不存在")
			}
			return err
		}
	}

	// 创建货物
	cargo := &model.Cargo{
		Code:         req.Code,
		Name:         req.Name,
		CategoryID:   req.CategoryID,
		SupplierID:   req.SupplierID,
		Unit:         req.Unit,
		Spec:         req.Spec,
		Price:        req.Price,
		Description:  req.Description,
		MinStock:     req.MinStock,
		MaxStock:     req.MaxStock,
		Status:       req.Status,
		StorageType:  req.StorageType,
		ShelfLife:    req.ShelfLife,
		Manufacturer: req.Manufacturer,
		Remark:       req.Remark,
	}

	err := global.DB.Create(cargo).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("创建货物", userID, "货物", cargo.ID, cargo.Name, "创建")
	}
	return err
}

// UpdateCargo 更新货物
func (s *CargoService) UpdateCargo(req *request.UpdateCargoRequest, userID uint) error {
	// 检查货物是否存在
	var cargo model.Cargo
	if err := global.DB.First(&cargo, req.ID).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("货物不存在")
		}
		return err
	}

	// 检查货物编码是否重复
	if req.Code != "" && req.Code != cargo.Code {
		var count int64
		if err := global.DB.Model(&model.Cargo{}).Where("code = ?", req.Code).Count(&count).Error; err != nil {
			return err
		}
		if count > 0 {
			return errors.New("货物编码已存在")
		}
	}

	// 如果更新分类ID，检查分类是否存在
	if req.CategoryID > 0 && req.CategoryID != cargo.CategoryID {
		var category model.CargoCategory
		if err := global.DB.First(&category, req.CategoryID).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return errors.New("货物分类不存在")
			}
			return err
		}
	}

	// 如果更新供应商ID，检查供应商是否存在
	if req.SupplierID != nil && (cargo.SupplierID == nil || *req.SupplierID != *cargo.SupplierID) {
		if *req.SupplierID > 0 {
			var supplier model.Supplier
			if err := global.DB.First(&supplier, *req.SupplierID).Error; err != nil {
				if errors.Is(err, gorm.ErrRecordNotFound) {
					return errors.New("供应商不存在")
				}
				return err
			}
		}
	}

	// 更新货物信息
	updates := map[string]interface{}{
		"code":         req.Code,
		"name":         req.Name,
		"category_id":  req.CategoryID,
		"supplier_id":  req.SupplierID,
		"unit":         req.Unit,
		"spec":         req.Spec,
		"price":        req.Price,
		"description":  req.Description,
		"min_stock":    req.MinStock,
		"max_stock":    req.MaxStock,
		"status":       req.Status,
		"storage_type": req.StorageType,
		"shelf_life":   req.ShelfLife,
		"manufacturer": req.Manufacturer,
		"remark":       req.Remark,
	}

	err := global.DB.Model(&cargo).Updates(utils.RemoveEmptyFields(updates)).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("更新货物", userID, "货物", req.ID, req.Name, "更新")
	}
	return err
}

// DeleteCargo 删除货物
func (s *CargoService) DeleteCargo(id uint, userID uint) error {
	// 检查货物是否存在
	var cargo model.Cargo
	if err := global.DB.First(&cargo, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("货物不存在")
		}
		return err
	}

	// 检查是否有关联的库存记录
	var count int64
	if err := global.DB.Model(&model.Inventory{}).Where("cargo_id = ?", id).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("货物存在库存记录，无法删除")
	}

	err := global.DB.Delete(&cargo).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("删除货物", userID, "货物", id, cargo.Name, "删除")
	}
	return err
}

// GetCargo 获取货物详情
func (s *CargoService) GetCargo(id uint) (*model.Cargo, error) {
	var cargo model.Cargo
	if err := global.DB.Preload("Category").Preload("Supplier").First(&cargo, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("货物不存在")
		}
		return nil, err
	}
	return &cargo, nil
}

// ListCargos 获取货物列表
func (s *CargoService) ListCargos(req *request.ListCargoRequest) ([]*model.Cargo, int64, error) {
	var cargos []*model.Cargo
	var total int64

	// 构建基础查询
	query := global.DB.Model(&model.Cargo{})

	// 添加查询条件
	if req.Keyword != "" {
		query = query.Where("code LIKE ? OR name LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}
	if req.CategoryID > 0 {
		query = query.Where("category_id = ?", req.CategoryID)
	}
	if req.Status > 0 {
		query = query.Where("status = ?", req.Status)
	}

	// 使用相同的查询条件获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 获取分页数据
	offset := (req.Page - 1) * req.PageSize
	if err := query.Preload("Category").Preload("Supplier").Offset(offset).Limit(req.PageSize).Find(&cargos).Error; err != nil {
		return nil, 0, err
	}

	return cargos, total, nil
}

// CreateCategory 创建货物分类
func (s *CargoService) CreateCategory(req *request.CreateCargoCategoryRequest, userID uint) error {
	// 检查编码是否已存在
	var count int64
	if err := global.DB.Model(&model.CargoCategory{}).Where("code = ?", req.Code).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("分类编码已存在")
	}

	// 检查名称是否已存在
	if err := global.DB.Model(&model.CargoCategory{}).Where("name = ?", req.Name).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("分类名称已存在")
	}

	// 创建分类
	category := &model.CargoCategory{
		Code: req.Code,
		Name: req.Name,
		Sort: req.Sort,
		// 移除不存在的字段
		// Description: req.Description,
	}

	err := global.DB.Create(category).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("创建分类", userID, "货物分类", category.ID, category.Name, "创建")
	}
	return err
}

// UpdateCategory 更新货物分类
func (s *CargoService) UpdateCategory(req *request.UpdateCargoCategoryRequest, userID uint) error {
	// 检查分类是否存在
	var category model.CargoCategory
	if err := global.DB.First(&category, req.ID).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("货物分类不存在")
		}
		return err
	}

	// 检查编码是否重复 - 假设字段名是Name而不是Code
	if req.Name != "" && req.Name != category.Name {
		var count int64
		if err := global.DB.Model(&model.CargoCategory{}).Where("name = ?", req.Name).Count(&count).Error; err != nil {
			return err
		}
		if count > 0 {
			return errors.New("分类名称已存在")
		}
	}

	// 更新分类 - 根据实际字段调整
	updates := map[string]interface{}{
		"name": req.Name,
		"sort": req.Sort,
		// 移除不存在的字段
		// "code": req.Code,
		// "description": req.Description,
	}

	err := global.DB.Model(&category).Updates(utils.RemoveEmptyFields(updates)).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("更新分类", userID, "货物分类", req.ID, req.Name, "更新")
	}
	return err
}

// DeleteCategory 删除货物分类
func (s *CargoService) DeleteCategory(id uint, userID uint) error {
	// 检查分类是否存在
	var category model.CargoCategory
	if err := global.DB.First(&category, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("货物分类不存在")
		}
		return err
	}

	// 检查是否有关联的货物
	var count int64
	if err := global.DB.Model(&model.Cargo{}).Where("category_id = ?", id).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("分类下存在货物，无法删除")
	}

	err := global.DB.Delete(&category).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("删除分类", userID, "货物分类", id, category.Name, "删除")
	}
	return err
}

// ListCategories 获取货物分类列表
func (s *CargoService) ListCategories(req *request.ListCargoCategoryRequest) ([]*model.CargoCategory, error) {
	var categories []*model.CargoCategory

	db := global.DB.Model(&model.CargoCategory{})

	// 添加查询条件
	if req.Keyword != "" {
		db = db.Where("code LIKE ? OR name LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 按排序字段排序
	db = db.Order("sort ASC")

	// 获取数据
	if err := db.Find(&categories).Error; err != nil {
		return nil, err
	}

	return categories, nil
}

// GetCategory 获取货物分类详情
func (s *CargoService) GetCategory(id uint) (*model.CargoCategory, error) {
	var category model.CargoCategory
	if err := global.DB.First(&category, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("货物分类不存在")
		}
		return nil, err
	}
	return &category, nil
}

// GetBatchCargos 批量获取货物信息
func (s *CargoService) GetBatchCargos(ids []uint) ([]*model.Cargo, error) {
	var cargos []*model.Cargo
	if err := global.DB.Preload("Category").Preload("Supplier").Where("id IN ?", ids).Find(&cargos).Error; err != nil {
		return nil, err
	}
	return cargos, nil
}

// UpdateCargoCategory 更新货品类别
func (s *CargoService) UpdateCargoCategory(req *request.UpdateCargoCategoryRequest, userID uint) error {
	var category model.CargoCategory
	err := global.DB.First(&category, req.ID).Error
	if err != nil {
		return errors.New("货品类别不存在")
	}

	category.Name = req.Name
	category.Code = req.Code
	// Description字段不存在于CargoCategory模型中，移除
	category.ParentID = req.ParentID
	category.Sort = req.Sort
	category.Status = req.Status
	category.Remark = req.Remark
	category.Level = req.Level

	err = global.DB.Save(&category).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("更新分类", userID, "货物分类", category.ID, category.Name, "更新")
	}

	return err
}

// CreateCargoCategory 创建货品类别
func (s *CargoService) CreateCargoCategory(req *request.CreateCargoCategoryRequest, userID uint) (uint, error) {
	category := model.CargoCategory{
		Name:     req.Name,
		Code:     req.Code,
		ParentID: req.ParentID,
		Level:    req.Level,
		Sort:     req.Sort,
		Status:   req.Status,
		Remark:   req.Remark,
	}

	err := global.DB.Create(&category).Error
	if err == nil {
		// 使用数据操作日志记录
		logger.LogDataOperation("创建分类", userID, "货物分类", category.ID, category.Name, "创建")
	}

	return category.ID, err
}
